package com.jacen.fzxs.util;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.jacen.fzxs.entity.webservice.RequestParam;
import com.jacen.fzxs.entity.webservice.Response;
import com.jacen.fzxs.entity.webservice.ResponseState;
import com.jacen.fzxs.exception.WebException;
import com.jacen.fzxs.service.app.IAppHandlerService;

public class WebServiceUtil {
	
	private static Map<String, String> handlerMap = new HashMap<String, String>();
	static{
		handlerMap.put("1001", "loginHandlerService");
		handlerMap.put("2001", "wallHandlerService");
		handlerMap.put("2002", "wallInfoHandlerService");
		handlerMap.put("3001", "addWallHandlerService");
	}
	
	public static String handler(String requestXml, ServletContext context, HttpServletRequest request) throws WebException{
		Document doc = null;
		try {
			doc = DocumentHelper.parseText(requestXml);
		} catch (DocumentException e) {
			throw new WebException("报文格式异常");
		}
		Element root = doc.getRootElement();
		RequestParam requestParam = WebServiceUtil.parseRequestParam(root.element("requestParam"));
		if (requestParam == null || requestParam.getRequestCode() == null) {
			throw new WebException("请求参数不能为空");
		}
		IAppHandlerService handlerService = getHandlerService(requestParam.getRequestCode(),context);
		String responeXml = "";
		try {
			responeXml = handlerService.handler(root.element("data"), request);
		} catch (WebException e) {
			if(e.getMessage()!=null && !"".equals(e.getMessage())){
				responeXml = e.getMessage();
			}else{
				responeXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
						+ "<response><responseState><code>99</code><description>未知异常</description><errorList><error>"+e.getMessage()+"</error></errorList></responseState></response>";
			}
		}
		return responeXml;
	}
	
	public static IAppHandlerService getHandlerService(String requestCode,ServletContext context){
		WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(context);
		return (IAppHandlerService) springContext.getBean(handlerMap.get(requestCode));
	}

	/**
	 * 解析元素为请求参数实体
	 * 
	 * @param element
	 * @return
	 */
	public static RequestParam parseRequestParam(Element element) {
		RequestParam requestParam = new RequestParam();
		Dom2EntityUtil.parseElement(requestParam, element);
		return requestParam;
	}
	
	/**
	 * 将回复实体转换成xml文档
	 * 
	 * @param <T>
	 * @param <E>
	 * @param response
	 * @param dataFormatUtil
	 *            用于解析data元素
	 * @return
	 * @throws WebServiceException
	 */
	public static <T, E extends BaseDataFormatUtil<T>> Document formatResponse(Response<T> response, E dataFormatUtil)
			throws WebException {
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement("response");
		ResponseState responseState = response.getResponseState();
		if (!(responseState.getCode() == ResponseState.CODE.SUCCESS)) {
			List<String> list = responseState.getErrorList();
			if (list == null || list.size() < 1) {
				responseState.addError(responseState.getDescription());
			}
		}
		Element responseStatusEle = formatResponseStatus(response.getResponseState(), root);
		if (responseStatusEle == null) {
			throw new WebException("回复状态不能为空");
		}
		if (response.getData() != null) {
			dataFormatUtil.formatData(response.getData(), root.addElement("data"));
		}
		return doc;
	}

	/**
	 * 格式化返回状态实体
	 * 
	 * @param responseState
	 * @param parentElement
	 * @return
	 */
	public static Element formatResponseStatus(ResponseState responseState, Element parentElement) {
		Element element = parentElement.addElement("responseState");
		Element codeElem = element.addElement("code");
		codeElem.setText(String.valueOf(responseState.getCode()));
		if (responseState.getDescription() != null) {
			Element descriptionElem = element.addElement("description");
			descriptionElem.setText(String.valueOf(responseState.getDescription()));
		}
		List<String> errorList = responseState.getErrorList();
		if (errorList != null && errorList.size() > 0) {
			Element errorListElem = element.addElement("errorList");
			for (String error : errorList) {
				Element errorElem = errorListElem.addElement("error");
				errorElem.setText(error);
			}
		}
		return element;
	}
}
